﻿using Innvoice.Logica.GestorObject.Articulo;
using Innvoice.BaseDeDatos.innvoicedbDataSetTableAdapters;
using System.Windows.Documents;
using System.Collections.Generic;
using System;
using System.Data;
using MySql.Data.MySqlClient;
using System.Windows;

namespace Innvoice.Logica.GestorDB
{
    public class ArticuloDB
    {

        /**
         * SUB ARTICULOS
         */

        #region SubArticulo

        #region CRUD SubArticulo

        public void AddSubArticulo(SubArticulo subArticulo)
        {
            int resultadoConsulta;

            subarticuloTableAdapter subArticuloTableAdapter = new subarticuloTableAdapter();
            var subArticuloDataTable = subArticuloTableAdapter.GetData();

            subArticuloTableAdapter.Connection.Open();

            MySqlTransaction transaccion = subArticuloTableAdapter.Connection.BeginTransaction();

            try
            {
                int codigo = subArticuloDataTable.Count + 1;
                string descripcion = subArticulo.Descripcion.ToUpper();
                decimal precioNeto = subArticulo.PrecioNeto;
                int codigoArticulo = subArticulo.CodigoArticulo;

                resultadoConsulta = subArticuloTableAdapter.InsertSubArticulo((short)codigo, descripcion, (decimal)precioNeto, (short)codigoArticulo, 1);

                transaccion.Commit();

                if (resultadoConsulta == 1)
                {
                    MessageBox.Show("Operacion de inserción exitosa", "Información", MessageBoxButton.OK);
                }
            }
            catch (Exception e)
            {
                transaccion.Rollback();
                MessageBox.Show("Error AddSubArticulo - ArticuloDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                subArticuloTableAdapter.Connection.Close();
            }

            
        }

        private void UpdateSubArticulo(int codigo, string descripcion, int codigoArticulo, decimal precioNeto, byte activo, bool mensajeConfirmacion)
        {

            int resultadoConsulta;

            subarticuloTableAdapter subArticuloTableAdapter = new subarticuloTableAdapter();

            subArticuloTableAdapter.Connection.Open();

            MySqlTransaction transaccion = subArticuloTableAdapter.Connection.BeginTransaction();

            try
            {
                resultadoConsulta = subArticuloTableAdapter.UpdateSubArticulo(descripcion.ToUpper(), precioNeto, (short)codigoArticulo, activo, (short)codigo);
                transaccion.Commit();

                if (resultadoConsulta == 1 && mensajeConfirmacion)
                {
                    MessageBox.Show("Operacion de actualización exitosa", "Información", MessageBoxButton.OK);
                }
            }
            catch (Exception e)
            {
                transaccion.Rollback();
                MessageBox.Show("Error UpdateSubArticulo - ArticuloDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                subArticuloTableAdapter.Connection.Close();
            }
        }

        public SubArticulo ObtenerSubArticulo(int indice)
        {
            subarticuloTableAdapter subArticuloTablaAdapter = new subarticuloTableAdapter();

            SubArticulo subArticulo = new SubArticulo();

            try
            {
                DataTable resultadoConsulta = subArticuloTablaAdapter.GetDataObtenerSubArticulo((short)indice);

                foreach (DataRow item in resultadoConsulta.Rows)
                {
                    subArticulo.Codigo = Convert.ToInt16(item["codigo_subArticulo"].ToString());
                    subArticulo.Descripcion = item["descripcion"].ToString();
                    subArticulo.PrecioNeto = decimal.Parse(item["precio"].ToString());
                    subArticulo.CodigoArticulo = Convert.ToInt16(item["codigo_articulo"].ToString());
                    subArticulo.CategoriaDescripcion = item["categoriaDescripcion"].ToString();
                    subArticulo.ArticuloDescripcion = item["articuloDescripcion"].ToString();
                    subArticulo.Activo = Convert.ToByte(item["activo"]); 
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "Error -- Class ArticuloDB -- Methods ObtenerSubArticulo(int indice)", "Cuidado", MessageBoxButton.OK);
            }

            return subArticulo;
        }

        #endregion

        public List<SubArticulo> ObtenerSubArticulosConDescripcion(int indiceArticulo)
        {
            List<SubArticulo> resultados = new List<SubArticulo>();
            resultados.Clear();

            subarticuloTableAdapter dbSubArticulo = new subarticuloTableAdapter();

            try
            {
                DataTable tablaSubArticulos = new DataTable();

                if (indiceArticulo == -1)
                    tablaSubArticulos = dbSubArticulo.GetDataBySubArticulosDescripcion();
                else
                    tablaSubArticulos = dbSubArticulo.GetDataBySubArticuloConCodigoArticulo((short)indiceArticulo);

                if (tablaSubArticulos.Rows.Count > 0) 
                {
                    foreach (DataRow items in tablaSubArticulos.Rows)
                    {
                        SubArticulo subArticulo = new SubArticulo();

                        subArticulo.Codigo = Convert.ToInt16(items["codigo_subArticulo"].ToString());
                        subArticulo.Descripcion = items["descripcion"].ToString();
                        subArticulo.PrecioNeto = decimal.Parse(items["precio"].ToString());
                        subArticulo.CodigoArticulo = Convert.ToInt16(items["codigo_articulo"].ToString());
                        subArticulo.CategoriaDescripcion = items["categoriaDescripcion"].ToString();
                        subArticulo.ArticuloDescripcion = items["articuloDescripcion"].ToString();
                        subArticulo.Activo = Convert.ToByte(items["activo"]); 

                        resultados.Add(subArticulo);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + " Error -- Class ArticuloDB -- Methods ObtenerSubArticulosConDescripcion()", "Cuidado", MessageBoxButton.OK);
            }

            return resultados;
        }

        public List<SubArticulo> ObtenerSubArticulosConDescripcion(Articulo articulo)
        {
            return ObtenerSubArticulosConDescripcion(articulo.Codigo);
        }

        public void UpdateSubArticulo(SubArticulo subArticulo, bool mensajeConfirmacion)
        {
            UpdateSubArticulo(subArticulo.Codigo, subArticulo.Descripcion, subArticulo.CodigoArticulo, subArticulo.PrecioNeto, subArticulo.Activo, mensajeConfirmacion);
        }

        public void DesactivarSubArticulo(SubArticulo subArticulo)
        {
            SubArticulo subArticuloAux = subArticulo;
            subArticuloAux.Activo = 0;
            UpdateSubArticulo(subArticuloAux, false);
        }

        public List<SubArticulo> ObtenerSubArticulosSegunEstado(byte activo)
        {
            List<SubArticulo> resultados = new List<SubArticulo>();
            resultados.Clear();

            subarticuloTableAdapter dbSubArticulo = new subarticuloTableAdapter();

            try
            {
                DataTable tablaSubArticulos = new DataTable();

                tablaSubArticulos = dbSubArticulo.GetDataBySubArticuloSegunEstado(activo);

                if (tablaSubArticulos.Rows.Count > 0)
                {
                    foreach (DataRow items in tablaSubArticulos.Rows)
                    {
                        SubArticulo subArticulo = new SubArticulo();

                        subArticulo.Codigo = Convert.ToInt16(items["codigo_subArticulo"].ToString());
                        subArticulo.Descripcion = items["descripcion"].ToString();
                        subArticulo.PrecioNeto = decimal.Parse(items["precio"].ToString());
                        subArticulo.CodigoArticulo = Convert.ToInt16(items["codigo_articulo"].ToString());
                        subArticulo.CategoriaDescripcion = items["categoriaDescripcion"].ToString();
                        subArticulo.ArticuloDescripcion = items["articuloDescripcion"].ToString();
                        subArticulo.Activo = Convert.ToByte(items["activo"]); 

                        resultados.Add(subArticulo);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + " Error -- Class ArticuloDB -- Methods ObtenerSubArticulosConDescripcion()", "Cuidado", MessageBoxButton.OK);
            }

            return resultados;
        }

        #endregion

        /**
         * ARTICULOS
         */

        #region Articulo

        #region CRUD Articulo

        //Agrega el articulo a la base de datos
        public void AddArticulo(Articulo articulo)
        {
            int resultadoConsulta;

            articuloTableAdapter articuloTableAdapter = new articuloTableAdapter();
            var articuloDataTable = articuloTableAdapter.GetDataByArticulo();
            articuloTableAdapter.Connection.Open();

            MySqlTransaction transaccion = articuloTableAdapter.Connection.BeginTransaction();

            try 
            {
                int codigo = articuloDataTable.Count + 1;
                string descripcion = articulo.Descripcion.ToUpper();
                int codigocategoria = articulo.CodigoCategoriaArticulo;

                resultadoConsulta = articuloTableAdapter.InsertArticulo((short)codigo, descripcion, (short)codigocategoria,1);

                transaccion.Commit();

                if (resultadoConsulta == 1)
                {
                    MessageBox.Show("Operacion de inserción exitosa", "Información", MessageBoxButton.OK);
                }

            }
            catch (Exception e)
            {
                transaccion.Rollback();
                MessageBox.Show("Error AddArticulo - ArticuloDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                articuloTableAdapter.Connection.Close();
            }
        }

        //Actualizar el articulo
        private void UpdateArticulo(int codigo, string descripcion, int codigoCategoria, byte activo, bool mensajeConfirmacion)
        {

            int resultadoConsulta;

            articuloTableAdapter articuloTablaAdapter = new articuloTableAdapter();

            articuloTablaAdapter.Connection.Open();

            MySqlTransaction transaccion = articuloTablaAdapter.Connection.BeginTransaction();

            try
            {
                resultadoConsulta = articuloTablaAdapter.UpdateArticulo(descripcion.ToUpper(), (short)codigoCategoria, activo, (short)codigo);
                transaccion.Commit();

                if (resultadoConsulta == 1 && mensajeConfirmacion)
                {
                    MessageBox.Show("Operacion de actualización exitosa", "Información", MessageBoxButton.OK);
                }
            }
            catch (Exception e)
            {
                transaccion.Rollback();
                MessageBox.Show("Error UpdateArticulo - ArticuloDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                articuloTablaAdapter.Connection.Close();
            }
        }

        public Articulo ObtenerArticulo(int indice)
        {
            articuloTableAdapter articuloTablaAdapter = new articuloTableAdapter();

            Articulo articulo = new Articulo();

            try
            {
                DataTable resultadoConsulta = articuloTablaAdapter.GetDataObtenerArticulo((short)indice);

                foreach (DataRow item in resultadoConsulta.Rows)
                {
                    articulo.Codigo = Convert.ToInt16(item["codigo_articulo"]);
                    articulo.Descripcion = item["descripcion"].ToString();
                    articulo.CodigoCategoriaArticulo = Convert.ToInt16(item["codigo_categoria"]);
                    articulo.CodigoCategoriaDescripcion = item["categoriaDescripcion"].ToString();
                    articulo.Activo = Convert.ToByte(item["activo"]);
                }
            }
            catch (Exception e) 
            {
                MessageBox.Show(e.Message + "Error -- Class ArticuloDB -- Methods ObtenerArticulo(int indice)", "Cuidado", MessageBoxButton.OK);
            }

            return articulo;
        }

        #endregion CRUD Articulo

        /** Obtiene una lista de Articulos de la Base de datos segun el indice de la categoria pasada
         * -1 Todos los articulos
         */
        public List<Articulo> ObtenerArticulos(int indiceCategoria)
        {
            List<Articulo> resultados = new List<Articulo>();
            resultados.Clear();

            articuloTableAdapter dbArticulo = new articuloTableAdapter();

            try
            {
                DataTable tablaArticulos = new DataTable();

                if (indiceCategoria == -1)
                    tablaArticulos = dbArticulo.GetDataByCategoriasArticulos();
                else
                    tablaArticulos = dbArticulo.GetDataByArticulosSegunCategoria((short)indiceCategoria);

                if (tablaArticulos.Rows.Count > 0)
                {
                    foreach (DataRow items in tablaArticulos.Rows)
                    {
                        Articulo articulo = new Articulo();

                        articulo.Codigo = Convert.ToInt16(items["codigo_articulo"]);
                        articulo.Descripcion = items["descripcion"].ToString();
                        articulo.CodigoCategoriaArticulo = Convert.ToInt16(items["codigo_categoria"]);
                        articulo.CodigoCategoriaDescripcion = items["categoriaDescripcion"].ToString();
                        articulo.Activo = Convert.ToByte(items["activo"]);

                        resultados.Add(articulo);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "Error -- Class ArticuloDB -- Methods ObtenerCategoriasDeArticulos()", "Cuidado", MessageBoxButton.OK);
            }

            return resultados;
        }

        public List<Articulo> ObtenerArticulosSegunEstado(byte activo)
        {
            List<Articulo> resultados = new List<Articulo>();
            resultados.Clear();

            articuloTableAdapter dbArticulo = new articuloTableAdapter();

            try
            {

                DataTable tablaArticulos = dbArticulo.GetDataByArticuloSegunEstado((byte)activo);

                if (tablaArticulos.Rows.Count > 0)
                {
                    foreach (DataRow items in tablaArticulos.Rows)
                    {
                        Articulo articulo = new Articulo();

                        articulo.Codigo = Convert.ToInt16(items["codigo_articulo"]);
                        articulo.Descripcion = items["descripcion"].ToString();
                        articulo.CodigoCategoriaArticulo = Convert.ToInt16(items["codigo_categoria"]);
                        articulo.CodigoCategoriaDescripcion = items["categoriaDescripcion"].ToString();
                        articulo.Activo = Convert.ToByte(items["activo"]);

                        resultados.Add(articulo);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "Error -- Class ArticuloDB -- Methods ObtenerArticulosSegunEstado(activo)", "Cuidado", MessageBoxButton.OK);
            }

            return resultados;
        }

        public void UpdateArticulo(Articulo articulo, bool mensajeConfirmacion)
        {
            UpdateArticulo(articulo.Codigo, articulo.Descripcion, articulo.CodigoCategoriaArticulo, articulo.Activo, mensajeConfirmacion);
        }

        public void DesactivarArticulo(Articulo articulo) 
        {
            articuloTableAdapter articuloTablaAdapter = new articuloTableAdapter();

            articuloTablaAdapter.Connection.Open();

            MySqlTransaction transaccion = articuloTablaAdapter.Connection.BeginTransaction();

            List<SubArticulo> subArticulosDelArticulo = ObtenerSubArticulosConDescripcion(articulo);

            int cantidadSubArticulos = subArticulosDelArticulo.Count;

            if (cantidadSubArticulos > 0)
            {
                foreach (SubArticulo item in subArticulosDelArticulo)
                {
                    DesactivarSubArticulo(item);
                }
            }

            try 
            {
                Articulo articuloAux = ObtenerArticulo(articulo.Codigo);

                articuloAux.Activo = 0;

                UpdateArticulo(articuloAux, false);
            }
            catch (Exception e)
            {
                MessageBox.Show("Error DesactivarArticulo(articulo) - ArticuloDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                articuloTablaAdapter.Connection.Close();
            }

        }

        #endregion

        /**
         * CATEGORIAS
         */

        #region Categoria

        #region CRUD Categoria

        public void AddCategoriaArticulo(CategoriaArticulo categoria)
        {
            int resultadoConsulta;

            categoriaTableAdapter categoriaTableAdapter = new categoriaTableAdapter();
            var categoriaDataTable = categoriaTableAdapter.GetDataByCategoria();
            categoriaTableAdapter.Connection.Open();

            MySqlTransaction transaccion = categoriaTableAdapter.Connection.BeginTransaction();

            try 
            {
               
                int codigo = categoriaDataTable.Count + 1;
                string descripcion = categoria.Descripcion.ToUpper();

                resultadoConsulta = categoriaTableAdapter.InsertCategoriaValues((short)codigo, descripcion,1);

                transaccion.Commit();

                if (resultadoConsulta == 1)
                {
                    MessageBox.Show("Operacion de inserción exitosa", "Información", MessageBoxButton.OK);
                }

            }
            catch (Exception e)
            {
                transaccion.Rollback(); 
                MessageBox.Show("Error AddCategoriaArticulo - ArticuloDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                categoriaTableAdapter.Connection.Close();
            }
            
        }

        private void UpdateCategoriaArticulo(int codigo, string descripcion, byte activo, bool mensajeConfirmacion)
        {

            int resultadoConsulta;

            categoriaTableAdapter categoriaTableAdapter = new categoriaTableAdapter();

            categoriaTableAdapter.Connection.Open();

            MySqlTransaction transaccion = categoriaTableAdapter.Connection.BeginTransaction();

            try
            {
                resultadoConsulta = categoriaTableAdapter.UpdateCategoria(descripcion.ToUpper(),activo, (short)codigo);
                transaccion.Commit();

                if (resultadoConsulta == 1 && mensajeConfirmacion)
                {
                    MessageBox.Show("Operacion de actualización exitosa", "Información", MessageBoxButton.OK);
                }
            }
            catch (Exception e)
            {
                transaccion.Rollback();
                MessageBox.Show("Error UpdateCategoriaArticulo - ArticuloDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                categoriaTableAdapter.Connection.Close();
            }
        }

        public List<CategoriaArticulo> ObtenerCategoriasDeArticulosSegunEstado(byte activo)
        {
            List<CategoriaArticulo> resultados = new List<CategoriaArticulo>();
            resultados.Clear();

            categoriaTableAdapter dbCategoriasArticulo = new categoriaTableAdapter();

            try
            {

                DataTable tablaCategoriasArticulos = dbCategoriasArticulo.GetDataByCategoriasArticuloByEstado(activo);

                if (tablaCategoriasArticulos.Rows.Count > 0)
                {
                    foreach (DataRow items in tablaCategoriasArticulos.Rows)
                    {
                        CategoriaArticulo categoriaArticulo = new CategoriaArticulo();

                        categoriaArticulo.Codigo = Convert.ToInt16(items["codigo_categoria"]);
                        categoriaArticulo.Descripcion = items["descripcion"].ToString();
                        categoriaArticulo.Activo = Convert.ToByte(items["activo"]);

                        resultados.Add(categoriaArticulo);
                    }
                }    
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "Error -- Class ArticuloDB -- Methods ObtenerCategoriasDeArticulosSegunEstado(activo)", "Cuidado", MessageBoxButton.OK);
            }

            return resultados;
        }

        /** Usado para el Listar Categorias
         */
        public List<CategoriaArticulo> ObtenerCategoriasDeArticulos()
        {
            List<CategoriaArticulo> resultados = new List<CategoriaArticulo>();
            resultados.Clear();

            categoriaTableAdapter dbCategoriasArticulo = new categoriaTableAdapter();

            try
            {

                DataTable tablaCategoriasArticulos = dbCategoriasArticulo.GetDataByCategoria();

                if (tablaCategoriasArticulos.Rows.Count > 0)
                {
                    foreach (DataRow items in tablaCategoriasArticulos.Rows)
                    {
                        CategoriaArticulo categoriaArticulo = new CategoriaArticulo();

                        categoriaArticulo.Codigo = Convert.ToInt16(items["codigo_categoria"]);
                        categoriaArticulo.Descripcion = items["descripcion"].ToString();
                        categoriaArticulo.Activo = Convert.ToByte(items["activo"]);

                        resultados.Add(categoriaArticulo);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "Error -- Class ArticuloDB -- Methods ObtenerCategoriasDeArticulos()", "Cuidado", MessageBoxButton.OK);
            }

            return resultados;
        }

        public CategoriaArticulo ObtenerCategoriaDeArticulos(int indice)
        {
            categoriaTableAdapter categoriaTablaAdapter = new categoriaTableAdapter();

            CategoriaArticulo categoria = new CategoriaArticulo();

            try
            {
                DataTable resultadoConsulta = categoriaTablaAdapter.GetDataByObtenerCategoria((short) indice);

                foreach (DataRow item in resultadoConsulta.Rows)
                {
                    categoria.Codigo = Convert.ToInt16(item["codigo_categoria"]);
                    categoria.Descripcion = item["descripcion"].ToString();
                    categoria.Activo = Convert.ToByte(item["activo"]);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "Error -- Class ArticuloDB -- Methods ObtenerCategoriaArticulo(int indice)", "Cuidado", MessageBoxButton.OK);
            }

            return categoria;
        }

        #endregion CRUD Categoria

        public void UpdateCategoriaArticulo(CategoriaArticulo categoriaArticulo, bool mensajeConfirmacion)
        {
            UpdateCategoriaArticulo(categoriaArticulo.Codigo, categoriaArticulo.Descripcion, categoriaArticulo.Activo, mensajeConfirmacion);
        }

        public void DesactivarCategoriaArticulo(CategoriaArticulo categoriaArticulo)
        {
            categoriaTableAdapter categoriaTablaAdapter = new categoriaTableAdapter();

            categoriaTablaAdapter.Connection.Open();

            MySqlTransaction transaccion = categoriaTablaAdapter.Connection.BeginTransaction();

            List<Articulo> articulosDeLaCategoria = ObtenerArticulos(categoriaArticulo.Codigo);

            int cantidadArticulos = articulosDeLaCategoria.Count;

            if (cantidadArticulos > 0)
            {
                foreach (Articulo item in articulosDeLaCategoria)
                {
                    DesactivarArticulo(item);
                }
            }

            try
            {
                CategoriaArticulo categoriaAux = ObtenerCategoriaDeArticulos(categoriaArticulo.Codigo);

                categoriaAux.Activo = 0;

                UpdateCategoriaArticulo(categoriaAux, false);
            }
            catch (Exception e)
            {
                MessageBox.Show("Error DesactivarCategoriaArticulo(categoriaArticulo) - ArticuloDB" + e.Message, "Cuidado", MessageBoxButton.OK);
            }
            finally
            {
                categoriaTablaAdapter.Connection.Close();
            }
        }

        #endregion Categoria


    }
}
